package com.mxpio.erp.equipment.service.impl;

import com.mxpio.erp.common.equipment.entity.EquipmentMaterialCategory;
import com.mxpio.erp.common.equipment.service.EquipmentMaterialCategoryService;
import com.mxpioframework.common.exception.MBootException;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.jpa.query.Criteria;
import com.mxpioframework.jpa.query.Operator;
import com.mxpioframework.system.service.impl.BaseServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;

/**
 * 备品分类Service业务层处理
 *
 * @author chenqiang
 * @date 2023-10-28
 */
@Service
public class EquipmentMaterialCategoryServiceImpl extends BaseServiceImpl<EquipmentMaterialCategory> implements EquipmentMaterialCategoryService {
    /**
     * 根节点父ID的值
     */
    public static final String ROOT_PID_VALUE = "0";

    @Override
    @Transactional
    public void addEquipmentMatCategory(EquipmentMaterialCategory equipmentMatCategory) {
        equipmentMatCategory.setHasChild(false);
        if (StringUtils.isBlank(equipmentMatCategory.getPid())
                || ROOT_PID_VALUE.equals(equipmentMatCategory.getPid())) {
            equipmentMatCategory.setPid(ROOT_PID_VALUE);
        } else {
            //如果当前节点父ID不为空 则设置父节点的hasChildren 为1
            EquipmentMaterialCategory parent = getById(EquipmentMaterialCategory.class, equipmentMatCategory.getPid());
            if (parent != null) {
                if (!parent.getHasChild()) {
                    this.updateTreeNodeStatus(parent.getId(), true);
                }
            }

        }
        this.save(equipmentMatCategory);
    }

    @Override
    @Transactional
    public void deleteEquipmentMatCategory(String id) {
        //查询选中节点下所有子节点一并删除
        id = this.queryTreeChildIds(id);
        if (id.indexOf(",") > 0) {
            StringBuffer sb = new StringBuffer();
            String[] idArr = id.split(",");
            for (String idVal : idArr) {
                if (StringUtils.isNotBlank(idVal)) {
                    EquipmentMaterialCategory equipmentMatCategory = this.getById(EquipmentMaterialCategory.class, idVal);
                    if (equipmentMatCategory != null) {
                        String pidVal = equipmentMatCategory.getPid();
                        //查询此节点上一级是否还有其他子节点
                        Long count = JpaUtil.linq(EquipmentMaterialCategory.class).equal("pid", pidVal).notIn("id", Arrays.asList(idArr)).count();
                        if ((count == null || count == 0) && !Arrays.asList(idArr).contains(pidVal)
                                && !sb.toString().contains(pidVal)) {
                            //如果当前节点原本有子节点 现在木有了，更新状态
                            sb.append(pidVal).append(",");
                        }
                    }
                }
            }
            //批量删除节点
            Criteria c = Criteria.create().addCriterion("id", Operator.IN, Arrays.asList(idArr));
            this.deleteBatch(EquipmentMaterialCategory.class, c);
            //修改已无子节点的标识
            String[] pidArr = sb.toString().split(",");
            for (String pid : pidArr) {
                this.updateOldParentNode(pid);
            }
        } else {
            EquipmentMaterialCategory equipmentMatCategory = getById(EquipmentMaterialCategory.class, id);
            if (equipmentMatCategory != null) {
                this.delete(EquipmentMaterialCategory.class, id);
                this.updateOldParentNode(equipmentMatCategory.getPid());
            }
        }
    }

    @Override
    @Transactional(readOnly = false)
    public void updateEquipmentMatCategory(EquipmentMaterialCategory equipmentMatCategory) {
        EquipmentMaterialCategory entity = this.getById(EquipmentMaterialCategory.class, equipmentMatCategory.getId());
        if (entity == null) {
            throw new MBootException("未找到对应记录！");
        }
        String old_pid = entity.getPid();
        String new_pid = equipmentMatCategory.getPid();
        if (!old_pid.equals(new_pid)) {
            this.updateOldParentNode(old_pid);
            if (StringUtils.isBlank(new_pid)) {
                equipmentMatCategory.setPid(ROOT_PID_VALUE);
            }
            if (!ROOT_PID_VALUE.equals(equipmentMatCategory.getPid())) {
                this.updateTreeNodeStatus(equipmentMatCategory.getPid(), true);
            }
        }
        this.update(equipmentMatCategory);

    }


    public void updateTreeNodeStatus(String id, Boolean hasChild) {
        JpaUtil.linu(EquipmentMaterialCategory.class).set("hasChild", hasChild).equal("id", id).update();
    }

    /**
     * 根据id查询所有子节点id
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional(readOnly = true)
    public String queryTreeChildIds(String ids) {
        //获取id数组
        String[] idArr = ids.split(",");
        StringBuffer sb = new StringBuffer();
        for (String pidVal : idArr) {
            if (pidVal != null) {
                if (!sb.toString().contains(pidVal)) {
                    if (sb.toString().length() > 0) {
                        sb.append(",");
                    }
                    sb.append(pidVal);
                    this.getTreeChildIds(pidVal, sb);
                }
            }
        }
        return sb.toString();
    }

    /**
     * 递归查询所有子节点
     *
     * @param pidVal
     * @param sb
     * @return
     */
    private StringBuffer getTreeChildIds(String pidVal, StringBuffer sb) {
        List<EquipmentMaterialCategory> dataList = JpaUtil.linq(EquipmentMaterialCategory.class).equal("pid", pidVal).list();
        if (dataList != null && dataList.size() > 0) {
            for (EquipmentMaterialCategory tree : dataList) {
                if (!sb.toString().contains(tree.getId())) {
                    sb.append(",").append(tree.getId());
                }
                this.getTreeChildIds(tree.getId(), sb);
            }
        }
        return sb;
    }

    /**
     * 根据所传pid查询旧的父级节点的子节点并修改相应状态值
     *
     * @param pid
     */
    public void updateOldParentNode(String pid) {
        if (!ROOT_PID_VALUE.equals(pid)) {
            Long count = JpaUtil.linq(EquipmentMaterialCategory.class).equal("pid", pid).count();
            if (count == null || count <= 1) {
                updateTreeNodeStatus(pid, false);
            }
        }
    }

}
